﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PlaceHR.Processor.Processor.Salary.Steps
{
    class WelfareSalaryStepCalculator : StepCalculatorBase<SalaryProcessorContext, EmployeeSalary>
    {
        public override void Calculate(SalaryProcessorContext salaryProcessorContext, EmployeeSalary employeeSalary)
        {
            decimal totalSalary = (employeeSalary.BasicSalary ?? 0)
                                     + (employeeSalary.PositionSalary ?? 0)
                                     + (employeeSalary.Bonus ?? 0)
                                     + (employeeSalary.Others ?? 0)
                                     -  (employeeSalary.SickLeave ?? 0)
                                     -  (employeeSalary.UnpaidLeave ?? 0);

            SalarySettings salarySettings = salaryProcessorContext.CurrentSalarySettings;
            EmployeeSalaryDetail employeeSalaryDetail = employeeSalary.EmployeeSalaryDetail.FirstOrDefault();

            //计算公积金
            decimal fundBase = totalSalary;
            fundBase = fundBase > salarySettings.Base_Fund_Max ? salarySettings.Base_Fund_Max : fundBase;
            fundBase = fundBase < salarySettings.Base_Fund_Min ? salarySettings.Base_Fund_Min : fundBase;
            employeeSalary.HousingFundCompany = fundBase * salarySettings.Fund_Company / 100;
            employeeSalary.HousingFundIndividual = fundBase * salarySettings.Fund_Personal / 100;

            //计算社保基数
            decimal socialBase = totalSalary;
            socialBase = socialBase > salarySettings.Base_Social_Max ? salarySettings.Base_Social_Max : socialBase;
            socialBase = socialBase < salarySettings.Base_Social_Min ? salarySettings.Base_Social_Min : socialBase;

            //计算养老保险
            decimal pensionBase = this.GetSocialDetailBase(totalSalary, socialBase, salarySettings.Base_Pension_Min, salarySettings.Base_Pension_Max);
            employeeSalaryDetail.Pension_Company_Percent = salarySettings.Pension_Company;
            employeeSalaryDetail.Pension_Personal_Percent = salarySettings.Pension_Personal;
            employeeSalaryDetail.Pension_Company_Money = pensionBase * salarySettings.Pension_Company / 100;
            employeeSalaryDetail.Pension_Personal_Money = pensionBase * salarySettings.Pension_Personal / 100;

            //计算医疗保险
            decimal medicalBase = this.GetSocialDetailBase(totalSalary, socialBase, salarySettings.Base_Medical_Min, salarySettings.Base_Medical_Max);
            employeeSalaryDetail.Medical_Company_Percent = salarySettings.Medical_Company;
            employeeSalaryDetail.Medical_Personal_Percent = salarySettings.Medical_Personal;
            employeeSalaryDetail.Medical_Company_Money = medicalBase * salarySettings.Medical_Company / 100;
            employeeSalaryDetail.Medical_Personal_Money = medicalBase * salarySettings.Medical_Personal / 100;

            //计算失业保险
            decimal unEmploymentBase = this.GetSocialDetailBase(totalSalary, socialBase, salarySettings.Base_Unemployment_Min, salarySettings.Base_Unemployment_Max);
            employeeSalaryDetail.Unemployment_Company_Percent = salarySettings.Unemployment_Company;
            employeeSalaryDetail.Unemployment_Personal_Percent = salarySettings.Unemployment_Personal;
            employeeSalaryDetail.Unemployment_Company_Money = unEmploymentBase * salarySettings.Unemployment_Company / 100;
            employeeSalaryDetail.Unemployment_Personal_Money = unEmploymentBase * salarySettings.Unemployment_Personal / 100;

            //计算工伤保险
            decimal injuryBase = this.GetSocialDetailBase(totalSalary, socialBase, salarySettings.Base_Injury_Min, salarySettings.Base_Injury_Max);
            employeeSalaryDetail.Injury_Company_Percent = salarySettings.Injury_Company;
            employeeSalaryDetail.Injury_Personal_Percent = salarySettings.Injury_Personal;
            employeeSalaryDetail.Injury_Company_Money = injuryBase * salarySettings.Injury_Company / 100;
            employeeSalaryDetail.Injury_Personal_Money = injuryBase * salarySettings.Injury_Personal / 100;

            //计算生育保险
            decimal maternityBase = this.GetSocialDetailBase(totalSalary, socialBase, salarySettings.Base_Maternity_Min, salarySettings.Base_Maternity_Max);
            employeeSalaryDetail.Maternity_Company_Percent = salarySettings.Maternity_Company;
            employeeSalaryDetail.Maternity_Personal_Percent = salarySettings.Maternity_Personal;
            employeeSalaryDetail.Maternity_Company_Money = maternityBase * salarySettings.Maternity_Company / 100;
            employeeSalaryDetail.Maternity_Personal_Money = maternityBase * salarySettings.Maternity_Personal / 100;

            //计算大病保险
            decimal seriousIllnessBase = this.GetSocialDetailBase(totalSalary, socialBase, salarySettings.Base_SeriousIllness_Min, salarySettings.Base_SeriousIllness_Max);
            employeeSalaryDetail.SeriousIllness_Company_Percent = salarySettings.SeriousIllness_Company;
            employeeSalaryDetail.SeriousIllness_Personal_Percent = salarySettings.SeriousIllness_Personal;
            employeeSalaryDetail.SeriousIllness_Company_Money = seriousIllnessBase * salarySettings.SeriousIllness_Company / 100;
            employeeSalaryDetail.SeriousIllness_Personal_Money = seriousIllnessBase * salarySettings.SeriousIllness_Personal / 100;

            //计算社保总数据
            employeeSalaryDetail.Social_Company_Percent = employeeSalaryDetail.Pension_Company_Percent
                                                                          + employeeSalaryDetail.Medical_Company_Percent
                                                                          + employeeSalaryDetail.Unemployment_Company_Percent
                                                                          + employeeSalaryDetail.Injury_Company_Percent
                                                                          + employeeSalaryDetail.Maternity_Company_Percent
                                                                          + employeeSalaryDetail.SeriousIllness_Company_Percent;

            employeeSalaryDetail.Social_Personal_Percent = employeeSalaryDetail.Pension_Personal_Percent
                                                                          + employeeSalaryDetail.Medical_Personal_Percent
                                                                          + employeeSalaryDetail.Unemployment_Personal_Percent
                                                                          + employeeSalaryDetail.Injury_Personal_Percent
                                                                          + employeeSalaryDetail.Maternity_Personal_Percent
                                                                          + employeeSalaryDetail.SeriousIllness_Personal_Percent;

            employeeSalaryDetail.Social_Company_Money = employeeSalaryDetail.Pension_Company_Money
                                                                          + employeeSalaryDetail.Medical_Company_Money
                                                                          + employeeSalaryDetail.Unemployment_Company_Money
                                                                          + employeeSalaryDetail.Injury_Company_Money
                                                                          + employeeSalaryDetail.Maternity_Company_Money
                                                                          + employeeSalaryDetail.SeriousIllness_Company_Money;

            employeeSalaryDetail.Social_Personal_Money = employeeSalaryDetail.Pension_Personal_Money
                                                                          + employeeSalaryDetail.Medical_Personal_Money
                                                                          + employeeSalaryDetail.Unemployment_Personal_Money
                                                                          + employeeSalaryDetail.Injury_Personal_Money
                                                                          + employeeSalaryDetail.Maternity_Personal_Money
                                                                          + employeeSalaryDetail.SeriousIllness_Personal_Money;

            employeeSalary.SocialInsuranceCompany = employeeSalaryDetail.Social_Company_Money;
            employeeSalary.SocialInsuranceIndividual = employeeSalaryDetail.Social_Personal_Money;

            employeeSalary.StaffWelfareFee = salarySettings.StaffWelfareFee;
        }

        /// <summary>
        /// 计算养老保险，工伤保险等每一项的基数
        /// </summary>
        /// <param name="totalSalary"></param>
        /// <param name="socialBase"></param>
        /// <param name="minBase"></param>
        /// <param name="maxbase"></param>
        /// <returns></returns>
        private decimal GetSocialDetailBase(decimal totalSalary, decimal socialBase, decimal minBase, decimal maxbase)
        {
            decimal resultBase = 0;
            if (minBase > totalSalary)
            {
                resultBase = minBase;
            }

            if (maxbase > 0 && maxbase < totalSalary)
            {
                resultBase = maxbase;
            }

            //如果这里依旧为0，说明该项没有限制，那么就取总的社保基数
            if (resultBase <= 0)
            {
                resultBase = socialBase;
            }

            return resultBase;
        }

    }
}
